<template>
	<view class="data-list-components safe-area-inset-bottom" :class="{ 'safe-area-inset-bottom': safeAreaInsetBottom }"
		:style="[dataListStyle]" @touchmove.stop.prevent>
		<scroll-view class="scroll-view" :scroll-top="scrollTop" :scroll-y="scrollingEnabled"
			:lower-threshold="lowerThreshold" :enable-back-to-top="enableBackToTop" @scroll="handleScroll"
			@scrolltolower="handleScrolltolower" @touchstart="handleTouchStart" @touchmove="handleTouchMove"
			@touchend="handleTouchEnd">
			<view class="scroll-content" :style="[scrollContentStyle]">
				<view class="pull-down-view">
					<slot name="refresh" v-if="$slots.refresh"></slot>
					<view class="refresh-view" v-else>
						<!-- <view class="loading-animation"></view> -->
						<!-- <view class="pull-down-animation"></view> -->
						<image src="/static/img/index/loading100x100.gif" style="width: 100rpx;" mode="widthFix"></image>
						<text class="pull-down-text">{{ refreshText[refreshStatus] }}</text>
					</view>
				</view>
				<view class="scroll-list">
					<slot :list="list" ></slot>
				</view>
				<view class="loading-view " v-if="loadStatus != 'nomore'">
					<!-- <view class="pull-down-animation"></view> -->
					<image src="/static/img/index/loading100x100.gif" style="width: 100rpx;" mode="widthFix"></image>
					<text class="loading-text">请稍后...</text>
				</view>
				<view class="empty-view" v-if="showEmpty">
					<slot name="empty" v-if="$slots.empty"></slot>
					<view class="empty-content" v-else>
						<image class="empty-image" :src="emptyImage || defaultEmptyImage" mode=""></image>
						<text class="empty-text">{{ emptyText }}</text>
					</view>
				</view>
				<view class="py-1">
					<view class="pull-up-view" v-if="!loadingMask && !showEmpty">
						<slot name="load" v-if="$slots.load"></slot>
						<view class="load-view" v-else>
							<!-- <view class="pull-down-animation" v-if="waiting&&loadStatus != 'nomore'"></view> -->
							<!-- <image src="/static/img/index/loading100x100.gif" style="width: 100rpx;" mode="widthFix"></image> -->
							<text class="loading-text">{{ loadText[loadStatus] }}</text>
						</view>
					</view>
				</view>
			</view>
		</scroll-view>
	</view>
</template>

<script>

	import emptyImages from './emptyImage.js';
		export default {
			name: 'data-list',
			props: {
				page: {
					type: [Number, String],
					default: 0
				},
				size: {
					type: [Number, String],
					default: 15
				},
				loading: {
					type: Boolean,
					default: true
				},
				safeAreaInsetBottom: {
					type: Boolean,
					default: true
				},
				emptyImage: {
					type: String
				},
				emptyText: {
					type: String,
					default: '暂无数据'
				},
				enableBackToTop: {
					type: Boolean,
					default: false
				},
				refresherThreshold: {
					type: [Number, String],
					default: 80
				},
				lowerThreshold: {
					type: [Number, String],
					default: 40
				},
				api:{
					type: String
				},
				params:{
					type: Object,
					default: {}
				},
				method:{
					type: String,
					default: 'GET'
				},
				resaultKey:{
					type: String,
					default: ''
				},
				timestamp: {
					type: Number,
					default: 0
				},
				autofresh:{
					type: Boolean,
					default: false
				},
				fixed:{
					type: Boolean,
					default: true
				},
				
			},
			watch: {
			   api(newV,oldV) {
				   this.refreshData() 
			   },
			   params(newV,oldV) {
				   //alert('ahahs s ')
				   this.refreshData() 	   
			   },
			   timestamp(newV,oldV) {
			   	   this.refreshData() 	   
			   } 
			},
			data() {
				return {
					list: [], // 数据列表
					total: -1, // 数据总数
					currentPage: 1, // 当前分页页码
					currentSize: 10, // 当前分页大小
					showEmpty: false, // 是否显示空数据
					waiting: false, // 是否等待加载中
					loadingMask: this.loading, // 是否显示加载中遮罩
					autoLoad: true, // 是否自动加载
					scrollTop: 0, // 设置竖向滚动条位置
					currentScrollTop: 0, // 当前竖向滚动条位置
					scrollingEnabled: true, // 是否启用竖向滚动
					pullingDown: false, // 是否正在下拉
					pullDownHeight: 0, // 下拉高度
					pullDownTimeStamp: 0, // 下拉时的时间戳
					loadStatus: 'loading',
					loadText: {
						loading: '请稍后...',
						loading: '',
						nomore: '暂无更多了'
					},
					refreshStatus: 'soon',
					refreshText: {
						soon: '继续下拉即可刷新',
						sure: '松开即可刷新',
						refreshing: '正在刷新中...'
					},
					defaultEmptyImage: emptyImages.data,
					componentsHeight: 'auto' ,// 组件高度属性
					dataList:[],
					queryList:[],
				};
			},
			computed: {
				dataListStyle() {
					const {
						componentsHeight
					} = this;
					return {
						height: componentsHeight
					};
				},
				scrollContentStyle() {
					const style = {};
					const {
						pullDownHeight,
						pullingDown
					} = this;
					style.transform = pullingDown ? `translateY(${pullDownHeight}px)` : `translateY(0px)`;
					style.transition = pullingDown ? `transform .1s linear` :
						`transform 0.3s cubic-bezier(0.19,1.64,0.42,0.72)`;
					return style;
				}
			},
			mounted() {
				this.handleInit();
				if(this.autofresh){
					this.refreshData() 
				}
				//this.refreshData() 
			},
			created(){
				
			},
			methods: {
				onQuery(e){
					if(e==1){
						this.refreshData()
					}
					console.log("onQuery",e)
				},
				contentHeightChanged(height){
					if(height === 0){
						//默认swiper高度为屏幕可用高度-tabsView高度-slot="top"内view的高度
						height = uni.getSystemInfoSync().windowHeight - topHeight;
					}
					this.pageHeight = height;
				},
				// 数据加载
				async loadMoreData() {
					this.autoLoad = false;
					this.showEmpty = false;
					await uni.sleep(100)
					this.waiting = true;
					this.loadStatus = 'loading'
					let page = this.currentPage
					let page_size = this.currentSize
					let offset = this.currentPage * this.currentSize
					let limit = this.currentSize
					
					let params = Object.assign({},this.params,{
						offset,
						limit
					})
					//无法去除对象中值为null的字段
					params = JSON.parse(JSON.stringify(params));
					let res  = null
					if(this.method == 'POST'){
						res = await uni.$http.post(`${this.api}`, params).catch((err) => {
							this.waiting = false;
							this.loadingMask = false;
						});
					}
					if(this.method == 'GET'){
						res = await uni.$http.get(`${this.api}`, params).catch((err) => {
							this.waiting = false;
							this.loadingMask = false;
						});
					}
					 
					let result = null;
					if(res.rows){
						if(Array.isArray(res.rows)){
							result = res.rows
						}
						if(this.resaultKey){
							result = res.data[this.resaultKey]
						}
					}
					if(!result || result.length == 0){
						this.autoLoad = false;
						//this.showEmpty = false;
						this.loadStatus = 'nomore';
					}
					console.log(res)
					this.waiting = false;
					this.loadingMask = false;
					this.currentPage++;
					//this.$refs['pagingRef'].complete();
					//this.list = res.data||[]
					this.list.push(...result||[]);
					this.$emit('loadMore', {
						page: this.currentPage,
						size: this.currentSize,
						list:result||[]
					}, res => {
						this.list = res.list;
						this.total = res.total;
					
					});
				},
				// 刷新数据
				async refreshData() {
					await uni.sleep(100)
					this.autoLoad = false;
					this.showEmpty = false;
					this.loadingMask = false;
					this.currentPage = this.page;
					this.currentSize = this.size;
					this.loadStatus = 'loading'
					let page = this.currentPage
					let page_size = this.currentSize
					let offset = this.currentPage* this.currentSize
					let limit = this.currentSize
					let params = Object.assign({},this.params,{
						offset,
						limit
					})
					params = JSON.parse(JSON.stringify(params));
					let res  = null
					console.log(this.method)
					if(this.method == 'POST'){
						res  = await uni.$http.post(`${this.api}`, params).catch((err) => {
							console.log(err)
							this.$emit('refresh', {
								page: this.currentPage,
								size: this.currentSize,
								list:[]
							})
							this.waiting = false;
							this.loadingMask = false;
							this.autoLoad = false;
							this.showEmpty = true;
							this.list = []
							this.autoLoad = true;
							this.pullingDown = false;
							this.pullDownHeight = 0;
							this.computedHeight();
						});
					}
					if(this.method == 'GET'){
						res  = await uni.$http.get(`${this.api}`, params).catch((err) => {
							console.log(err)
							this.$emit('refresh', {
								page: this.currentPage,
								size: this.currentSize,
								list:[]
							})
							this.waiting = false;
							this.loadingMask = false;
							this.autoLoad = false;
							this.showEmpty = true;
							this.list = []
							this.autoLoad = true;
							this.pullingDown = false;
							this.pullDownHeight = 0;
							this.computedHeight();
						});
					}
					//console.log(res)
					//this.$refs['pagingRef'].complete();
					this.waiting = false;
					
					this.currentPage++;
					this.autoLoad = true;
					this.pullingDown = false;
					this.pullDownHeight = 0;
					this.computedHeight();
					this.$emit('refresherrestore');
					
					let result = null;
					if(res.rows){
						if(Array.isArray(res.rows)){
							result = res.rows
						}
						
						if(this.resaultKey){
							result = res.data[this.resaultKey]
						}
					}
					
					if(!result){
						this.showEmpty = true;
						this.list = []
					}
					if(result && Array.isArray(result) && result.length==0){
						this.showEmpty = true;
						this.list = []
					}
					if(Array.isArray(result) && this.currentSize>result.length){
						//this.autoLoad = false;
						this.loadStatus = 'nomore';
					}
					console.log("result.length",result.length)
					console.log("this.currentSize",this.currentSize)
					console.log("this.loadStatus",this.loadStatus)
					//this.list = res.data||[]
					this.list = result||[];
					this.$emit('refresh', {
						page: this.currentPage,
						size: this.currentSize,
						list:result||[]
					}, res => {
						this.autoLoad = true;
						this.pullingDown = false;
						this.pullDownHeight = 0;
						this.list = res.list;
						this.total = res.total;
						this.currentPage++;
						//this.handleComputeData();
						this.computedHeight();
						this.$emit('refresherrestore');
					});
				},
				// 计算高度
				computedHeight() {
					this.getRect('.data-list-components').then(res => {
						// #ifdef H5
						this.componentsHeight = `calc(100vh - ${res.top}px - var(--window-top))`;
						// #endif
						// #ifndef H5
						this.componentsHeight = `calc(100vh - ${res.top}px)`;
						// #endif
						this.autoLoad = true;
						this.$nextTick(() => {
							//this.handleAutoLoadData();
						});
					});
				},
				// 自动加载数据
				async handleAutoLoadData() {
					if (this.autoLoad && this.loadStatus != 'nomore') {
						const components = await this.getRect('.data-list-components');
						const scrolList = await this.getRect('.scroll-list');
						if (scrolList.height <= components.height) {
							this.loadMoreData();
						} else {
							this.autoLoad = false;
						}
					}
				},
				// 计算数据
				handleComputeData() {
					const len = this.list.length;
					const total = this.total;
					if (len == 0 || total == 0) {
						this.autoLoad = false;
						this.showEmpty = true;
					} else if (len >= this.total) {
						this.autoLoad = false;
						this.showEmpty = false;
						this.loadStatus = 'nomore';
					} else if (len < this.total) {
						this.showEmpty = false;
						this.loadStatus = 'loading';
					}
				},
				// 上拉触底事件
				handleScrolltolower(e) {
					this.$emit('scrolltolower', e);
					if (this.loadStatus == 'nomore' || this.waiting) return;
					this.loadMoreData();
				},
				// 滚动事件
				handleScroll(e) {
					this.currentScrollTop = e.detail.scrollTop;
					this.$emit('scroll', e);
				},
				// 触摸按下处理
				handleTouchStart(e) {
					this.pullingDown = true;
					this.currentTouchStartY = e.touches[0].clientY;
				},
				// 触摸按下滑动处理
				handleTouchMove(e) {
					this.$emit('refresherpulling', e);
					if (e.touches[0].clientY < this.currentTouchStartY) return;
					const shakeInterval = 1000 / 60;
					const currentTimeStamp = new Date().getTime();
					if (this.pullDownTimeStamp && currentTimeStamp - this.pullDownTimeStamp <= shakeInterval) return;
					this.pullDownTimeStamp = currentTimeStamp;
					const currentTouchMoveY = e.touches[0].clientY;
					const movingDistance = (currentTouchMoveY - this.currentTouchStartY) * 0.7;
					const moreDistance = movingDistance > this.refresherThreshold ? (movingDistance - this
						.refresherThreshold) * 0.3 : 0;
					const computeDistance =
						movingDistance > this.refresherThreshold ? this.refresherThreshold + moreDistance : movingDistance +
						moreDistance;
					if (computeDistance >= this.refresherThreshold) {
						this.refreshStatus = 'sure';
					} else {
						this.refreshStatus = 'soon';
					}
					this.pullDownHeight = computeDistance;
				},
				// 触摸松开处理
				handleTouchEnd(e) {
					if (this.pullDownHeight < this.refresherThreshold) {
						this.pullingDown = false;
						this.pullDownHeight = 0;
						this.refreshStatus = 'soon';
						this.$emit('refresherabort', e);
					} else {
						this.pullDownHeight = this.refresherThreshold;
						this.refreshStatus = 'refreshing';
						this.$emit('refresherrefresh', e);
						this.refreshData();
					}
				},
				// 初始化
				handleInit() {
					this.currentPage = this.page;
					this.currentSize = this.size;
					this.computedHeight();
				},
				// 查询dom节点信息
				getRect(selector, all) {
					return new Promise(resolve => {
						uni.createSelectorQuery()
							.in(this)[all ? 'selectAll' : 'select'](selector)
							.boundingClientRect(rect => {
								if (all && Array.isArray(rect) && rect.length) {
									resolve(rect);
								}
								if (!all && rect) {
									resolve(rect);
								}
							})
							.exec();
					});
				}
			}
		};
	</script>
	
	<style scoped lang="scss">
		.pull-down-animation {
			width: 38rpx;
			height: 38rpx;
			border: .2em solid #00C09D;
			border-radius: 50%;
			-webkit-animation: pull-down-animation 1s ease-out infinite;
			animation: pull-down-animation 1s ease-out infinite;
		}
	
		@-webkit-keyframes pull-down-animation {
			0% {
				-webkit-transform: scale(0);
				transform: scale(0);
				opacity: 0;
			}
	
			50% {
				opacity: 1;
			}
	
			100% {
				-webkit-transform: scale(1);
				transform: scale(1);
				opacity: 0;
			}
		}
	
		@keyframes pull-down-animation {
			0% {
				-webkit-transform: scale(0);
				transform: scale(0);
				opacity: 0;
			}
	
			50% {
				opacity: 1;
			}
	
			100% {
				-webkit-transform: scale(1);
				transform: scale(1);
				opacity: 0;
			}
		}
	
	
		.pull-down-animation-02 {
			border: 0 solid transparent;
			border-radius: 50%;
			position: relative;
		}
	
		.pull-down-animation-02:before,
		.pull-down-animation-02:after {
			content: '';
			border: .2em solid currentcolor;
			border-radius: 50%;
			width: inherit;
			height: inherit;
			position: absolute;
			top: 0;
			left: 0;
			-webkit-animation: loader-07 1s linear infinite;
			animation: loader-07 1s linear infinite;
			opacity: 0;
		}
	
		.pull-down-animation-02:before {
			-webkit-animation-delay: 1s;
			animation-delay: 1s;
		}
	
		.pull-down-animation-02:after {
			-webkit-animation-delay: .5s;
			animation-delay: .5s;
		}
	
		@-webkit-keyframes pull-down-animation-02 {
			0% {
				-webkit-transform: scale(0);
				transform: scale(0);
				opacity: 0;
			}
	
			50% {
				opacity: 1;
			}
	
			100% {
				-webkit-transform: scale(1);
				transform: scale(1);
				opacity: 0;
			}
		}
	
		@keyframes pull-down-animation-02 {
			0% {
				-webkit-transform: scale(0);
				transform: scale(0);
				opacity: 0;
			}
	
			50% {
				opacity: 1;
			}
	
			100% {
				-webkit-transform: scale(1);
				transform: scale(1);
				opacity: 0;
			}
		}
	
	
		.data-list-components {
			height: 100%;
	
			.scroll-view {
				height: 100%;
	
				.scroll-content {
					width: 100%;
					height: 100%;
					position: relative;
	
					.empty-view {
						width: 100%;
						height: 50%;
						display: flex;
						align-items: center;
						justify-content: center;
	
						.empty-content {
							margin: auto;
							display: flex;
							align-items: center;
							flex-direction: column;
	
							.empty-image {
								width: 300rpx;
								height: 300rpx;
							}
	
							.empty-text {
								color: #AEACB9;
								font-size: 28rpx;
								margin-top: 20rpx;
							}
						}
					}
	
					.pull-down-view {
						top: 0;
						left: 0;
						width: 100%;
						padding: 30rpx 0;
						display: flex;
						position: absolute;
						align-items: center;
						flex-direction: column;
						justify-content: center;
						transform: translateY(-100%);
	
						.refresh-view {
							display: flex;
							align-items: center;
							flex-direction: column;
	
							.loading-animation {
								width: 50rpx;
								height: 50rpx;
							}
	
							.pull-down-text {
								color: #606266;
								font-size: 24rpx;
								margin-top: 10rpx;
							}
						}
					}
	
					.scroll-list {
						display: flex;
						flex-direction: column;
					}
	
					.loading-view {
						width: 100%;
						//height: 100%;
						display: flex;
						align-items: center;
						flex-direction: column;
						justify-content: center;
						margin-top: 50rpx;
						.loading-animation {
							width: 40rpx;
							height: 40rpx;
						}
	
						.loading-text {
							color: #AEACB9;
							font-size: 24rpx;
							margin-top: 10rpx;
						}
					}
	
					.pull-up-view {
						width: 100%;
						padding: 15rpx 0;
						display: flex;
						align-items: center;
						justify-content: center;
	
						.load-view {
							display: flex;
							align-items: center;
	
							.loading-animation {
								width: 30rpx;
								height: 30rpx;
							}
	
							.loading-text {
								color: #AEACB9;
								font-size: 24rpx;
								margin-left: 20rpx;
							}
						}
					}
	
					.loading-animation {
	
						position: relative;
	
						&::after,
						&::before {
							left: 0;
							width: 100%;
							position: absolute;
							border: 0 solid currentColor;
							background-color: #b7b7b7;
						}
	
						&::after {
							content: '';
							top: -25%;
							z-index: 1;
							height: 100%;
							border-radius: 10%;
							animation: spin 0.6s -0.1s linear infinite;
						}
	
						&::before {
							content: '';
							bottom: -9%;
							height: 10%;
							background: #000;
							border-radius: 50%;
							opacity: 0.2;
						}
	
						@keyframes spin {
							17% {}
	
							25% {
								transform: translateY(25%) rotate(22.5deg);
							}
	
							50% {
								transform: translateY(50%) rotate(45deg);
							}
	
							75% {
								transform: translateY(25%) rotate(67.5deg);
							}
	
							100% {
								transform: translateY(0) rotate(90deg);
							}
						}
	
					}
				}
			}
		}
	</style>
	
